#include "qttoolwidget.h"
#include "ui_qttoolwidget.h"
#include "ConversionObject.h"
#include "PATH.h"
#include <functional>


QtToolWidget::QtToolWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QtToolWidget)
{
    this->ui->setupUi(this);
    this->setAcceptDrops(true); //允许接受拖拽
    this->setMinimumSize(160,128);
    this->ui->setBtn->setIcon(QIcon(":/button_icon/three_points.svg"));
    this->connect(this->ui->selectFileButton, &QPushButton::clicked, this, &QtToolWidget::selectUiFileManually);
    this->connect(this,&QtToolWidget::FileInfos,this,&QtToolWidget::generateStartupArguments);
    this->connect(this,&QtToolWidget::StartupArguments,this,&QtToolWidget::conversion);

    // this->savePath = "D:/Desktop/CODE/C++/Qt/ui_Tool/uic/";
    // this->savePath = "./";暂时使用绝对路径，之后添加配置文件控制保存路径


    // 如果需要Qt5（基于PySide2）的py文件，可以使用Qt5的uic.exe或使用 Pyside2包中的 uic.exe
    // python的uic.exe默认生成.py文件，也可以生成C++文件，C++的uic.exe默认生成 .h文件，也可以生成.py文件
    // C++的ui文件大部分情况下可以不区分Qt版本（Qt5或Qt6）
    // 如果需要生成基于PyQt的py文件，需要使用PyQt包中的 uic.exe （因为PyQt不是Qt官方的 ? 雾）

    //下面这个exe可以生成C++ .h文件 和 基于PySide6的 .py文件
    // this->uicPath = "D:/Desktop/CODE/C++/Qt/ui_Tool/uic/uic_Qt6_MSVC2019_x64_release.exe";

    //暂时使用全局uic，之后添加配置文件使用相对路径uic
    this->uicPath = "uic.exe";//静态版本uic
    //this->uicPath = "./uic_Qt6_MSVC2019_x64_dynamic_release.exe";//动态版本uic

}

QtToolWidget::~QtToolWidget()
{
    delete this->ui;
}

void QtToolWidget::conversion(const QSharedPointer<QList<QSharedPointer<QStringList>>>& startupArguments)
{
    QThread* conversionThread = new QThread(this);//线程对象
    ConversionObject* conversionObj = new ConversionObject();//转换对象

    //线程对象启动时，转换对象的转换函数也启动
    this->connect(conversionThread,
                  &QThread::started,
                  conversionObj,
                  std::bind(&ConversionObject::startConversion,conversionObj,this->uicPath,startupArguments));

    //转换对象转换完成，释放内存
    this->connect(conversionObj,
                  &ConversionObject::conversionFinished,
                  this,
                  std::bind(&QtToolWidget::conversionFinished,this,conversionThread,conversionObj));

    conversionObj->moveToThread(conversionThread);
    conversionThread->start();
}

void QtToolWidget::conversionFinished( QThread * const conversionThread,ConversionObject * const conversionObj)
{
    conversionThread->quit();
    conversionThread->wait();
    conversionThread->deleteLater();
    conversionObj->deleteLater();
    // qDebug()<<"线程已结束，线程对象和转换对象已释放";
}

void QtToolWidget::generateStartupArguments(const QSharedPointer<QList<QSharedPointer<QFileInfo>>> &fileInfos)
{
    QSharedPointer<QList<QSharedPointer<QStringList>>> arguments(new QList<QSharedPointer<QStringList>>);

    for(auto& fileInfo : *fileInfos)
    {
        QString originalFileAbsolutePath = fileInfo->absoluteFilePath();//原始文件绝对路径

        //保存转换后的文件的路径，包含完整文件名，保存路径为原始文件路径同级目录
        // QString SaveConversionFileAbsolutePath = this->savePath+fileInfo->baseName()+".h";

        //暂时使用绝对路径(原始文件路径同级目录)
        QString SaveConversionFileAbsolutePath = fileInfo->absolutePath()+"/"+fileInfo->baseName()+"_ui.h";

        // 构造启动参数
        QSharedPointer<QStringList> argument(new QStringList());
        (*argument) << originalFileAbsolutePath << "-o" << SaveConversionFileAbsolutePath;
        (*arguments) << argument;
    }

    emit this->StartupArguments(arguments);
}

void QtToolWidget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasUrls())
        event->acceptProposedAction();
}

void QtToolWidget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasUrls())
    {
        QSharedPointer<QList<QSharedPointer<QFileInfo>>> fileInfoList(new QList<QSharedPointer<QFileInfo>>);

        for (const QUrl &fileUrl : event->mimeData()->urls())
        {
            QSharedPointer<QFileInfo> fileInfo(new QFileInfo(fileUrl.toLocalFile()));

            if (fileInfo->suffix().toLower() == "ui")
                fileInfoList->append(fileInfo);
            else
                QMessageBox::warning(this,"格式错误", fileInfo->fileName() + " 不是ui文件", QMessageBox::Ok);
        }
        if(!fileInfoList->isEmpty())
            emit this->FileInfos(fileInfoList);
    }
}

void QtToolWidget::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);
    quint16 x = this->width()/16;
    quint16 y = this->height()/8;
    // quint16 w = x*14;
    // quint16 h = y*6;

    QPainter painter(this);
    painter.setRenderHint(QPainter::RenderHint::Antialiasing);
    painter.setPen(Qt::PenStyle::DashLine);
    const_cast<QPen&>(painter.pen()).setWidth(1);
    painter.setBrush(Qt::GlobalColor::transparent);
    painter.drawRect(this->width()/16,this->height()/8,x*14,y*6);

}

void QtToolWidget::selectUiFileManually()
{
    QStringList filePaths = QFileDialog::getOpenFileNames(this,"选择ui文件",desktopPath,"ui文件 (*.ui)");

    if (!filePaths.isEmpty())
    {
        QSharedPointer<QList<QSharedPointer<QFileInfo>>> fileInfoList(new QList<QSharedPointer<QFileInfo>>);

        for (QString &filePath : filePaths)
        {
            QSharedPointer<QFileInfo> fileInfo(new QFileInfo(filePath));
            fileInfoList->append(fileInfo);
        }
        emit this->FileInfos(fileInfoList);
    }
}
